package com.iris.thread.countDownLatch;

import java.util.concurrent.CountDownLatch;

/**
 * 项目: thinking
 * 包名: com.iris.thread.countDownLatch
 * 作者: victor
 * 日期: 2016年11月1日
 * 说明: CountDownLatchTest
 * 利用它可以实现类似计数器的功能。比如有一个任务A，它要等待其他4个任务执行完毕之后才能执行，此时就可以利用CountDownLatch来实现这种功能了。
 * countDown()计数器减一
 * await达到条件后就执行后面的代码
 * 
 * 只能用一次,后面的计数就只有一次,为0后不可变
 * Barrier是等待指定数量线程到达再继续处理； 
	Latch是等待指定事件变为指定状态后发生再继续处理，对于CountDown就是计数减为0的事件，但你也可以实现或使用其他Latch就不是这个事件了... 
	Barrier是等待指定数量任务完成，Latch是等待其他任务完成指定状态的改变再继续。。。 
 * 
 */
public class CountDownLatchTest {

	public static void main(String[] args) {
		CountDownLatch cdl = new CountDownLatch(3);
		System.out.println("main=========");
		Thread th1= new Thread(new CountDownLatchRunnable(cdl),"th1");
		Thread th2= new Thread(new CountDownLatchRunnable(cdl),"th2");
		Thread th3= new Thread(new CountDownLatchRunnable(cdl),"th3");
		th1.start();
		th2.start();
		th3.start();
		try {
			System.out.println("cdl.await()");
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("main======end");
		
		/**
		 * CountDownLatch 只能用一次,后面的计数就只有一次,和CylicBarrier有所区别
		 */
		
//		Thread th4= new Thread(new CountDownLatchRunnable(cdl),"th4");
//		Thread th5= new Thread(new CountDownLatchRunnable(cdl),"th5");
//		Thread th6= new Thread(new CountDownLatchRunnable(cdl),"th6");
//		th4.start();
//		th5.start();
//		th6.start();
//		try {
//			System.out.println("cdl.await()");
//			cdl.await();
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//		System.out.println("main======end==========2");
	}
}

class CountDownLatchRunnable implements Runnable{
	private CountDownLatch cdl;
	public CountDownLatchRunnable(CountDownLatch cdl){
		this.cdl= cdl;
	}
	@Override
	public void run() {
		System.out.println("====CountDownLatchRunnable ==="+Thread.currentThread().getName()+"==="+cdl.getCount());
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		cdl.countDown();
		System.out.println("====CountDownLatchRunnable ===end=="+Thread.currentThread().getName()+"==="+cdl.getCount());
		try {
			Thread.sleep(1000);
			cdl.await();
			System.out.println("runnable=========await===end");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}


